package cn.com.company.common.redis;

import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import java.util.Collections;

/**
 * 
 * Title: JedisUtil<br>
 * Description: JedisUtil<br>
 * CreateDate:2020年6月21日 下午4:17:12
 * 
 */
@Component
public class JedisUtil {

  public static JedisPool jedisPool;

  @Resource
  public void setJedisPool(JedisPool jedisPool) {
    JedisUtil.jedisPool = jedisPool;
  }

  /**
   *
   * Title: 根据key获取value<br>
   * Description: 根据key获取value<br>
   * CreateDate: 2020年6月15日 下午3:35:57<br>
   *
   * @category 根据key获取value
   * @param key
   * @return
   * @throws Exception
   */
  public static String get(String key) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      return jedis.get(key);
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   * Title: 设置key-value形式数据<br>
   * Description: set<br>
   * CreateDate: 2020/4/17 15:22<br>
   *
   * @param key
   * @param value
   * @return void
   * @exception Exception
   */
  public static void set(String key, String value) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.set(key, value);
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   *
   * Title: 设置key-value形式数据<br>
   * Description: 设置key-value形式数据<br>
   * CreateDate: 2020年6月15日 下午3:35:15<br>
   *
   * @category 设置key-value形式数据
   * @param key
   * @param value
   * @throws Exception
   */
  public static void set(String key, String value, int expire) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.set(key, value);
      jedis.expire(key, expire);
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   *
   * Title: 返回哈希表key中指定域field的值<br>
   * Description: 返回哈希表key中指定域field的值<br>
   * CreateDate: 2020年6月15日 下午3:38:02<br>
   *
   * @category 返回哈希表key中指定域field的值
   * @param key
   * @param field
   * @return
   * @throws Exception
   */
  public static String hget(String key, String field) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      return jedis.hget(key, field);
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   *
   * Title: 为哈希表中的字段赋值<br>
   * Description: <br>
   * 为哈希表中的字段赋值,如果哈希表不存在,则创建新的哈希表并进行hset操作<br>
   * 如果字段已经存在于哈希表中,旧值将被覆盖,返回0<br>
   * 如果字段是哈希表中的一个新建字段,且值设置成功,返回 1<br>
   * CreateDate: 2020年6月15日 下午3:37:21<br>
   *
   * @category 为哈希表中的字段赋值
   * @param key
   * @param field
   * @param value
   * @return
   * @throws Exception
   */
  public static long hset(String key, String field, String value, int expire) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      Long hset = jedis.hset(key, field, value);
      jedis.expire(key, expire);
      return hset;
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   *
   * Title: 刷新过期时间<br>
   * Description: 刷新过期时间<br>
   * CreateDate: 2020年6月15日 下午3:37:09<br>
   *
   * @category 刷新过期时间
   * @param key
   * @param timeOut
   * @return
   * @throws Exception
   */
  public static long expire(String key, int timeOut) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      return jedis.expire(key, timeOut);
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   *
   * Title: 根据key获取过期时间(-1表示不过期)<br>
   * Description: 根据key获取过期时间(-1表示不过期)<br>
   * CreateDate: 2020年6月15日 下午3:36:41<br>
   *
   * @category 根据key获取过期时间(-1表示不过期)
   * @param key
   * @return
   * @throws Exception
   */
  public static long ttl(String key) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      return jedis.ttl(key);
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   *
   * Title: 根据key删除对应缓存<br>
   * Description: 根据key删除对应缓存<br>
   * CreateDate: 2020年6月15日 下午3:36:27<br>
   *
   * @category 根据key删除对应缓存
   * @param key
   * @throws Exception
   */
  public static void del(String key) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      jedis.del(key);
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   *
   * Title: 如果fields中有field存在于哈希中,则删除并返回1,否则返回0,不执行操作<br>
   * Description: 如果fields中有field存在于哈希中,则删除并返回1,否则返回0,不执行操作<br>
   * CreateDate: 2020年6月15日 下午3:39:43<br>
   *
   * @category 如果fields中有field存在于哈希中,则删除并返回1,否则返回0,不执行操作
   * @param key
   * @param fields
   * @return
   * @throws Exception
   */
  public static long hdel(String key, String... fields) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      return jedis.hdel(key, fields);
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   *
   * Title: 获取自增数字<br>
   * Description: 获取自增数字<br>
   * CreateDate: 2020年6月15日 下午3:39:43<br>
   *
   * @category 获取自增数字
   * @param key
   * @param expireTimeSeconds
   * @return
   * @throws Exception
   */
  public static long incr(String key, int expireTimeSeconds) throws Exception {
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      Long res = jedis.incr(key);
      jedis.expire(key, expireTimeSeconds);
      return res;
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
  }

  /**
   *
   * Title: 获取自增数字<br>
   * Description: 获取自增数字<br>
   * CreateDate: 2020年6月15日 下午3:39:43<br>
   *
   * @category 获取自增数字
   * @param key
   * @return
   * @throws Exception
   */
  public static long incr(String key) throws Exception {
    return incr(key, RedisConstant.EXPIRES_TIME_SECONDS);
  }

  /**
   * Title: 尝试获取分布式锁(没有则添加)<br>
   * Description: tryGetDistributedLock<br>
   * CreateDate: 2020/4/17 13:29<br>
   *
   * @param lockKey
   *          锁
   * @param requestId
   *          请求标识
   * @param expireTime
   *          超期时间
   * @return boolean
   * @exception Exception
   */
  public static boolean tryGetDistributedLock(String lockKey, String requestId,
      int expireTime) {
    boolean flag = false;
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      Long resultLong = jedis.setnx(lockKey, requestId);
      jedis.expire(lockKey, expireTime);
      if (RedisConstant.SET_SUCCESS.equals(resultLong)) {
        flag = true;
      }
      // String result = jedis.set(lockKey, requestId, RedisConstant.SET_IF_NOT_EXIST,
      // RedisConstant.SET_WITH_EXPIRE_TIME, expireTime);
      // if (RedisConstant.LOCK_SUCCESS.equals(result)) {
      // flag = true;
      // }
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
    return flag;
  }

  /**
   * Title: 释放分布式锁<br>
   * Description: releaseDistributedLock<br>
   * CreateDate: 2020/4/17 13:42<br>
   *
   * @param lockKey
   *          锁
   * @param requestId
   *          请求标识
   * @return boolean
   * @exception Exception
   */
  public static boolean releaseDistributedLock(String lockKey, String requestId) {
    boolean flag = false;
    String script =
        "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    Jedis jedis = null;
    try {
      jedis = jedisPool.getResource();
      Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections
          .singletonList(requestId));
      if (RedisConstant.RELEASE_SUCCESS.equals(result)) {
        flag = true;
      }
    } finally {
      // 返回连接对象到连接池
      jedis.close();
    }
    return flag;
  }

}
